﻿package rd.hardcore.engine.sound 
{
	import caurina.transitions.Tweener;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.SampleDataEvent;
	import flash.filesystem.File;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	import rd.debug.Debug;
	import rd.hardcore.engine.save.SaveManager;
	import rd.hardcore.engine.tools.Tools;
	import rd.hardcore.events.SoundSystemEvent;
	import rd.hardcore.ui.StopButton;
	
	/**
	 * Sound System
	 * instance : Main
	 * 
	 * @author Romain
	 */
	public class HardcoreGhettoSoundSystem extends EventDispatcher
	{
		
		static public const LIMIT	: int = 5;
		
		/* VAR */
		static public var a_sndChannel	: Array = [];
		static public var AUTO_RESSET_SPEED	: Boolean = true;
		public static var PSEUDO_8BITS 		: Boolean = false;
		
		/*	Vitesse de lecture	*/
		private var _playbackSpeed:Number = 1;	
		
		public var canal			: SoundChannel;
		public var volumeManager	: SoundTransform;
		public var proxyBtStop		: StopButton;
		
		private var currentVolume 	: Number;
		private var soundCpt		: int = 0;
		private var sndPlaying		: Boolean = false;
		/*	Mémorise	*/
		private var memSpeed		: Number = 1;
		private var closingSound	: Boolean = false;
		
		
		/* Hardcore Ghetto SoundSystem */
		public function HardcoreGhettoSoundSystem() 
		{
			currentVolume = 1;
			
			volumeManager 	= new SoundTransform();
			
			volumeManager.volume = currentVolume;
		}
		
		/* Play Sound */
		public function playSound( evt : SoundSystemEvent ) : void
		{
			//trace("Sound Channel Length: "+a_sndChannel.length);
			proxyBtStop.active();
			
			//secure
			if (a_sndChannel.length > LIMIT) return;
			
			var mapperSound:Sound = new Sound();

			var str : String = Tools.macOsUrlProofing( File.applicationStorageDirectory.nativePath + "/" + evt.track.file );
			
			var fichierMP3:URLRequest = new URLRequest( str );
			
			mapperSound.addEventListener(IOErrorEvent.IO_ERROR, handleError, false, 0, true);
			mapperSound.addEventListener(Event.COMPLETE, handleLoadingComplete);
			mapperSound.load(fichierMP3);
			
			
		}
		
		private function handleLoadingComplete(e:Event):void 
		{
			var hardcoreModifier:HardcoreSoundModifier = new HardcoreSoundModifier(e.currentTarget as Sound);
			sndPlaying = true;
			HardcoreSoundModifier.PLAYBACK_SPEED = playbackSpeed;
			var conteneurSon:Sound = new Sound();
			conteneurSon.addEventListener(SampleDataEvent.SAMPLE_DATA, hardcoreModifier.onSampleData);
			canal = conteneurSon.play();
			a_sndChannel.push(canal);
			canal.addEventListener(Event.SOUND_COMPLETE, closeSound);
			canal.soundTransform = volumeManager;
			soundCpt++;
			
			//conteneurSon = null;
		}
		
		
		/* Error Handler */
		private function handleError(e:IOErrorEvent):void 
		{
			reGenChannel();
		}
		
		public function closeSound( evt : Event ) : void
		{	
			// TWEEN REQUESTED
			if (evt == null)
			{
				closingSound = true;
				memSpeed = (AUTO_RESSET_SPEED)?1:playbackSpeed;
				Tweener.addTween(this, { playbackSpeed:.5, time:2 , onComplete:cleanSound } );
			
			// END DETECTED
			} else if (evt.type == Event.SOUND_COMPLETE) {
				Tweener.removeTweens(this);
				// NOT LAST SOUND
				if (soundCpt > 1)
					soundCpt--;
				// LAST SOUND 	
				else 
					cleanSound(evt);
			
			//KILL REQUESTED
			} else {
				Tweener.removeTweens(this);
				cleanSound();
			}
		}
		
		private function cleanSound(evt : Event = null):void
		{
			if(soundCpt > 0)	soundCpt--;
			
			if ((soundCpt == 0 || evt == null) && sndPlaying)
			{
				while (a_sndChannel.length > 0)
				{
					canal = a_sndChannel.pop();
					canal.stop();
					canal.removeEventListener(Event.SOUND_COMPLETE, closeSound);
					canal = null;
				}
				
				closingSound = false;
				dispatchEvent(new SoundSystemEvent(SoundSystemEvent.STOP_SOUND, null));
				
				soundCpt = 0;
				proxyBtStop.unactive();
				sndPlaying = false;
			}
			
			playbackSpeed = memSpeed;
			
			volumeManager.volume = currentVolume;
		}
		
		
		/* Channel Handler */
		private function reGenChannel() : void
		{
			if (canal) canal.stop();
			
			soundCpt = 0;
			
			canal 			= new SoundChannel();
			//conteneurSon 	= new Sound();
			
			volumeManager 	= new SoundTransform(currentVolume);
		}
		
		public function get playbackSpeed():Number { return _playbackSpeed; }
		
		public function set playbackSpeed(value:Number):void 
		{
			_playbackSpeed = (value < .01)? .01 : value;
			HardcoreSoundModifier.PLAYBACK_SPEED = _playbackSpeed;
			if(!closingSound)	memSpeed = _playbackSpeed;
		}
		
	}

}